package ar.uba.fi.algo3.programa;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JFrame;

import ar.uba.fi.algo3.control.ControlDePuntos;
import ar.uba.fi.algo3.control.ControladorDisparos;
import ar.uba.fi.algo3.control.ControladorFinDeJuego;
import ar.uba.fi.algo3.control.ControladorNaves;
import ar.uba.fi.algo3.modelo.BatallaNaval;
import ar.uba.fi.algo3.modelo.disparo.*;
import ar.uba.fi.algo3.modelo.nave.Nave;
import ar.uba.fi.algo3.vista.VistaDisparo;
import ar.uba.fi.algo3.vista.VistaNave;

import fiuba.algo3.titiritero.dibujables.SuperficiePanel;
import fiuba.algo3.titiritero.modelo.GameLoop;

public class Programa2 {
	
	private final static int ANCHO_VENTANA = 760;
    private final static int ALTO_VENTANA = 500;
   
    public static void main(String[] args) throws IOException {
        
    	SuperficiePanel panel = crearPanel();
    	JFrame ventana = new JFrame("Batalla Navalgo");
        crearVentana(panel, ventana);
        
        final GameLoop gameLoop = new GameLoop(panel);          
        final BatallaNaval juego = new BatallaNaval();
        
        ventana.getContentPane().add(getBotonDisparoConvencional(juego));
        ventana.getContentPane().add(getBotonMinaPuntual(juego));
        ventana.getContentPane().add(getBotonMinaDoble(juego));
        ventana.getContentPane().add(getBotonMinaTriple(juego));
        ventana.getContentPane().add(getBotonMinaPorContacto(juego));
               
        ControlDePuntos controlaPuntos = panelPuntaje(juego);
        ventana.getContentPane().add(controlaPuntos);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlaPuntos);

        ArrayList<Nave> naves= juego.getNaves();
        Iterator<Nave> iteradorDeNaves=naves.iterator();
        ArrayList<VistaNave> vistasNaves= new ArrayList<VistaNave>();
        while (iteradorDeNaves.hasNext()){
        	
        	Nave nave= iteradorDeNaves.next();
        	VistaNave vistaNave= new VistaNave(nave);
        	gameLoop.agregar(vistaNave);
            gameLoop.agregar(vistaNave.getPosicionable());
            vistasNaves.add(vistaNave);
        }
               
        final ControladorDisparos controladorDisparos = new ControladorDisparos(gameLoop);
        gameLoop.agregarObservador(controladorDisparos);
    
        ControladorFinDeJuego controlFinDeJuego = new ControladorFinDeJuego(juego,gameLoop);
        gameLoop.agregarObservador(controlFinDeJuego);
        
        ventana.getContentPane().addMouseListener(new java.awt.event.MouseAdapter() {
           
        	public void mousePressed(java.awt.event.MouseEvent e) {
                   
        		Disparo disparoElegido;
        		VistaDisparo vistaDisparo;
        		try {
        			if ((e.getY() < 500) && (e.getX() < 500)){        				
        				
        				disparoElegido = juego.disparar((e.getX()/50) ,(e.getY())/50);
        				vistaDisparo = new VistaDisparo(disparoElegido);
        				gameLoop.agregar(vistaDisparo);
        				controladorDisparos.agregar(vistaDisparo);
        			}
        		} catch (IOException e1) {
        			e1.printStackTrace();
        		}                    
        	}    
        });
        
        realizarBoxNaves(ventana, gameLoop, juego, vistasNaves);

        gameLoop.setFrecuencia(25);
        gameLoop.iniciarEjecucion();
        gameLoop.agregar(juego);
    }

	private static void realizarBoxNaves(JFrame ventana,
			final GameLoop gameLoop, final BatallaNaval juego,
			ArrayList<VistaNave> vistasNaves) {
		ControladorNaves controlNaves = new ControladorNaves(gameLoop, vistasNaves, juego);
        
        ventana.getContentPane().add(controlNaves.textNaves);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);              
        
        ventana.getContentPane().add(controlNaves.textNaveLancha1);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);

        ventana.getContentPane().add(controlNaves.textNaveLancha2);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);
        
        ventana.getContentPane().add(controlNaves.textNaveBuque);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);
        
        ventana.getContentPane().add(controlNaves.textNaveDestructor1);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);
        
        ventana.getContentPane().add(controlNaves.textNaveDestructor2);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);
        
        ventana.getContentPane().add(controlNaves.textNavePortaAviones);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);
        
        ventana.getContentPane().add(controlNaves.textNaveRompehielos);
        ventana.paintComponents(ventana.getGraphics());
        gameLoop.agregarObservador(controlNaves);
	}

	private static ControlDePuntos panelPuntaje(final BatallaNaval juego) {
		
		ControlDePuntos controlaPuntos = new ControlDePuntos(juego);
        controlaPuntos.setFont(new Font("", Font.BOLD, 20));
        controlaPuntos.setBounds(560, 0, 250, 40);
        controlaPuntos.setVisible(true);

        return controlaPuntos;
	}

	private static void crearVentana(SuperficiePanel panel, JFrame ventana ) {
		        
        ventana.getContentPane().setLayout(null);
        ventana.getContentPane().add(panel);  
        ventana.setBounds(0, 0, ANCHO_VENTANA, ALTO_VENTANA);
        ventana.setLocationRelativeTo(null);
        ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ventana.setForeground(new Color(3, 120, 0));
        ventana.setResizable(false);
        ventana.setVisible(true);              
        panel.setImagen(panel.createImage(500, 500));
	}

	private static SuperficiePanel crearPanel() {

		SuperficiePanel panel = new SuperficiePanel();
    	panel.setBackground(new Color(220, 233, 242));
    	panel.setBounds(0,0, 500, 500);
    	panel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		return panel;
	}
	
	private static JButton getBotonDisparoConvencional(BatallaNaval juego) {

		String informaPuntos= "200 puntos";
		return crearBoton("Disparo",new DisparoConvencional(null, null),40,juego,informaPuntos);				     
	}
	
	private static JButton getBotonMinaPuntual(BatallaNaval juego) {	
		
		String informaPuntos= "50 puntos";
		return crearBoton("Mina Submarina Puntual Con Retardo",new MinaSubmarinaPuntualConRetardo(null, null),80,juego, informaPuntos);
	}
	
	private static JButton getBotonMinaDoble(BatallaNaval juego) {	
		
		String informaPuntos= "100 puntos";
		return crearBoton("Mina Submarina Doble Con Retardo",new MinaSubmarinaDobleConRetardo(null, null),120,juego, informaPuntos);
	}
	
	private static JButton getBotonMinaTriple(BatallaNaval juego) {	
		
		String informaPuntos= "125 puntos";
		return crearBoton("Mina Submarina Triple Con Retardo",new MinaSubmarinaTripleConRetardo(null, null),160,juego, informaPuntos);
	}
	
	private static JButton getBotonMinaPorContacto(BatallaNaval juego) {	

		String informaPuntos= "150 puntos";
		return crearBoton("Mina Submarina Por Contacto",new MinaSubmarinaPorContacto(null, null),200,juego, informaPuntos);		
	}
	
	private static JButton crearBoton(String nombreDisparo, final Disparo disparo, int posicionY,final BatallaNaval juego, String informaPuntos) {          

		JButton boton = new JButton(nombreDisparo);
		boton.setBackground(Color.orange);
		boton.addActionListener(new ActionListener() {							   
        	
			@Override           
        	public void actionPerformed(ActionEvent e) {	

				juego.guardarDisparo(disparo);		
        	}		               
        });		        
		boton.setToolTipText(informaPuntos);

		boton.setBounds(500, posicionY, 250, 30);
        
        return boton;		       
	}
}
